package com.ellricky.baselib.http;

import android.app.Application;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.andr.common.http.NetConst;
import com.andr.common.http.util.JsonUtil;
import com.andr.common.util.NetUtil;
import com.ellricky.baselib.cache.LocalCacheUtil;
import com.ihsanbal.logging.Level;
import com.ihsanbal.logging.LoggingInterceptor;
import com.orhanobut.logger.Logger;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.builder.GetBuilder;
import com.zhy.http.okhttp.builder.OkHttpRequestBuilder;
import com.zhy.http.okhttp.builder.PostFormBuilder;
import com.zhy.http.okhttp.builder.PostStringBuilder;
import com.zhy.http.okhttp.callback.Callback;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.request.RequestCall;


import java.io.File;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;

import static com.zhy.http.okhttp.OkHttpUtils.initClient;

public class HttpUtils {
    private static HttpUtils mInstance;
    private Application mApp;
    private Map<String, Object> headerMap;

    private HttpUtils() {
    }

    public static HttpUtils getInstance() {
        if (mInstance == null) {
            synchronized (HttpUtils.class) {
                if (mInstance == null) {
                    mInstance = new HttpUtils();
                }
            }
        }
        return mInstance;
    }


    /**
     * 全局初始化 OkHttpClient
     */
    public void init(Application app) {
        mApp = app;
        //  设置可访问所有的https
        HttpLoggingInterceptor interceptor =
                new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        try {
                            Log.i("ellricky", message);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.e("ellricky", message);
                        }
                    }
                });

        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .addInterceptor(interceptor)
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS);


        OkHttpClient okHttpClient = okHttpClientBuilder.build();
        initClient(okHttpClient);
    }


//*************************************************************************************
// 异步 get
//*************************************************************************************

    public void get(String url, Callback callback) {
        get(url, null, callback);
    }


    /**
     * @param url          url
     * @param callback
     * @param parameterMap url参数
     */
    public void get(String url, Map<String, String> parameterMap, Callback callback) {
        if (TextUtils.isEmpty(url)) return;

        GetBuilder builder = OkHttpUtils.get()
                .url(url);
        if (parameterMap != null) {
            builder.params(parameterMap);
        }


        RequestCall requestCall = addHeader(builder).build();
        execute(requestCall, callback);
    }

///////////////////////////////////////////////////////////////////////////
//异步 post 请求
///////////////////////////////////////////////////////////////////////////

    public void post(String url, Map<String, Object> t, Callback callback) {
        post(url, t, callback, null);
    }

    public void postFrom(String url, Map<String, String> t, Callback callback) {
        postFrom(url, t, callback, null);
    }


    /**
     * @param t Map or  实体
     */
    public void postFrom(String url, Map<String, String> t, Callback callback, Object tag) {
        if (TextUtils.isEmpty(url)) return;

        PostFormBuilder builder = OkHttpUtils.post()
                .url(url)
                .params(t);
        if (tag != null) {
            builder.tag(tag);
        }

        RequestCall requestCall = addHeader(builder).build();

        execute(requestCall, callback);
    }

    /**
     * @param t Map or  实体
     */
    public void post(String url, Map<String, Object> t, Callback callback, Object tag) {
        if (TextUtils.isEmpty(url)) return;

        String content = JsonUtil.toJson2(t);

        PostStringBuilder builder = OkHttpUtils.postString()
                .url(url)
                .mediaType(NetConst.MEDIA_TYPE_PIC)
                .content(content);
        if (tag != null) {
            builder.tag(tag);
        }

        RequestCall requestCall = addHeader(builder).build();

        execute(requestCall, callback);
    }


//    public void postFile(String url, File file, Map<String, Object> t, Callback callback) {
//        if (checkNoNetwork()) return;
//        PostFileBuilder builder = OkHttpUtils.postFile()
//                .url(url);
//        builder.mediaType(NetConst.MEDIA_TYPE_PIC);
//        builder.file(file);
//
//        RequestCall requestCall = addHeader(builder).build();
//        execute(requestCall, callback);
//    }

    /**
     * 上传文件
     */

    public void uploadPhoto(String url, File file, Map<String, String> t, Callback callback) {
        if (checkNoNetwork()) return;
//        Map<String, String> params = new HashMap<>();
//        params.put("fileDescription", "");
//        params.put("fileName", "android.png");
//        params.put("sizes", "null,160#160");
        Logger.t("upload").e("%s", file.getAbsolutePath());

        PostFormBuilder builder = OkHttpUtils.post()
                .addFile("picFile", file.getName(), file)
                .url(url)
                .params(t);
//                .addHeader("Content-type","application/x-www-form-urlencoded");
        RequestCall requestCall = addHeader(builder).build();
        execute(requestCall, callback);
    }


//*************************************************************************************
// 同步post
//*************************************************************************************

//    public <T> void postSync(String url, T t, SyncCallback callback) {
//        if (TextUtils.isEmpty(url)) return;
//
//        String content = JsonUtil.toJson(t);
//
//
//        PostStringBuilder builder = OkHttpUtils.postString()
//                .url(url)
//                .mediaType(NetConst.MEDIA_TYPE_JSON)
//                .content(content);
//
//        RequestCall requestCall = addHeader(builder).build();
//        parseSyncResult(requestCall, callback);
//    }


///////////////////////////////////////////////////////////////////////////
// 私有方法
///////////////////////////////////////////////////////////////////////////

    private OkHttpRequestBuilder addHeader(OkHttpRequestBuilder builder) {
        if (mApp == null) throw new RuntimeException("please initial application first!!!");
        if (headerMap == null) {
            headerMap = new HashMap<>();
        }

        String token = LocalCacheUtil.getUToken();
        if (!TextUtils.isEmpty(token)) {
            headerMap.put(NetConst.UTOKEN, token);
        }

        headerMap.put("Content-Type", "application/x-www-form-urlencoded");
        return builder.headers(headerMap);
    }


    private void execute(RequestCall requestCall, Callback callback) {
        if (checkNoNetwork()) return;
        requestCall.execute(callback);
    }


//    private void parseSyncResult(RequestCall requestCall, SyncCallback callback) {
//        if (checkNoNetwork()) return;
//        try {
//            Response response = requestCall.execute();
//            if (response.isSuccessful()) {
//                String result = response.body().string();
//                callback.onSuccess(result);
//            } else {
//                callback.onFail(response.code());
//            }
//
//        } catch (IOException e) {
//            e.printStackTrace();
//            callback.onError(e);
//        }
//    }

    private boolean checkNoNetwork() {
        if (mApp == null) throw new RuntimeException("please initial application first!!!");
        Context context = mApp.getApplicationContext();
        return !NetUtil.isConnected(context);
    }

    public void cancelTag(Object tag) {
        OkHttpUtils.getInstance().cancelTag(tag);
    }

}

